package com.atguigu.jxc.service.impl;

import com.atguigu.jxc.dao.*;
import com.atguigu.jxc.domain.ErrorCode;
import com.atguigu.jxc.domain.ServiceVO;
import com.atguigu.jxc.domain.SuccessCode;
import com.atguigu.jxc.entity.*;
import com.atguigu.jxc.service.*;
import com.atguigu.jxc.util.ResultUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl extends ServiceImpl<GoodsDao, Goods> implements GoodsService {
    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private DamageListGoodsDao damageListGoodsDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private PurchaseListService purchaseListService;
    @Autowired
    private PurchaseListGoodsService purchaseListGoodsService;
    @Autowired
    private ReturnListService returnListService;
    @Autowired
    private ReturnListGoodsService returnListGoodsService;
    @Autowired
    private ReturnListDao returnListDao;


    @Override
    public Map<String, Object> listInventory(Integer page, Integer rows, String codeOrName, Integer goodsTypeId) {
        List<Integer> goodsTypeIdList = new ArrayList<>();
        if (goodsTypeId != null) {
            // 不是一级分类id
            if (goodsTypeId != 1) {
                // 如果是一级分类id, 查询所有商品
                GoodsType goodsType = goodsDao.selectGoodsTypeById(goodsTypeId);
                Integer goodsTypeState = goodsType.getGoodsTypeState();
                // 如果是二级分类id，找出二级下的所有三级的goodsTypeId
                if (goodsTypeState == 1) {
                    goodsTypeIdList = goodsDao.selectGoodsTypeIdListByPid(goodsTypeId);
                } else {
                    // 三级分类id的话，直接添加到集合
                    goodsTypeIdList.add(goodsTypeId);
                }
            }
        }

        // 计算limit 的索引值 limit 0,30
        Integer index = (page - 1) * rows;
        // 查询goods的列表
        List<Goods> goodsList = goodsDao.selectPage(index, rows, codeOrName, goodsTypeIdList);
        // 查询goods的数量
        Integer count = goodsDao.selectCountOfGoods(codeOrName, goodsTypeIdList);
        // 组装数量
        Map<String, Object> map = new HashMap<>();

        map.put("total", count);
        map.put("rows", goodsList);
        return map;
    }


    @Override
    public List<Map> loadGoodsType() {
        List<GoodsType> goodsTypeList = goodsDao.selectListOfGoodsType();
        // 构造集合数据
        List<Map> mapList = new ArrayList<>();

        // 一级分类
        GoodsType goodsType = goodsTypeList.get(0);
        Map<String, Object> goodsTypeMap1 = toMap(goodsType, goodsType.getGoodsTypeState());
        // 把一级放list中
        mapList.add(goodsTypeMap1);

        // 筛选出二级分类
        List<GoodsType> goodsTypeList2 = goodsTypeList.stream().filter(goodsType1 -> goodsType1.getPId() == 1).collect(Collectors.toList());

        // 筛选出三级分类
        List<GoodsType> GoodsTypeList3 = goodsTypeList.stream().filter(goodsType1 -> goodsType1.getGoodsTypeState() == 0).collect(Collectors.toList());

        // 二级分类
        List<Map> mapList2 = new ArrayList<>();
        for (GoodsType goodsType2 : goodsTypeList2) {
            Map<String, Object> goodsTypeMap2 = toMap(goodsType2, goodsType2.getGoodsTypeState());
            mapList2.add(goodsTypeMap2);
            // 三级分类
            List<Map> mapList3 = new ArrayList<>();
            for (GoodsType goodType3 : GoodsTypeList3) {
                // 三级分类属于二级分类
                if (goodsType2.getGoodsTypeId() == goodType3.getPId()) {
                    // 生成map结构
                    Map<String, Object> goodsTypeMap3 = toMap(goodType3, goodType3.getGoodsTypeState());
                    mapList3.add(goodsTypeMap3);
                }
            }
            // 把三级放入二级
            goodsTypeMap2.put("children", mapList3);
        }
        // 把二级放入一级
        goodsTypeMap1.put("children", mapList2);

        return mapList;
    }

    /**
     * 转化GoodsType到map格式
     *
     * @param goodsType
     * @param goodsTypeState
     * @return
     */
    private Map<String, Object> toMap(GoodsType goodsType, Integer goodsTypeState) {
        Map<String, Object> map = new HashMap<>();
        map.put("id", goodsType.getGoodsTypeId());
        map.put("text", goodsType.getGoodsTypeName());

        Map<String, Integer> subMap = new HashMap<>();
        if (goodsTypeState == 1) {
            // 1，父节点
            map.put("state", "closed");
            subMap.put("state", 1);
            map.put("attributes", subMap);
        } else {
            // 0, 叶子节点
            map.put("state", "open");
            subMap.put("state", 0);
            map.put("attributes", subMap);
        }
        map.put("iconCls", "goods-type");
        return map;
    }

    /**
     * 查询商品所有的单位
     * @return
     */
    @Override
    public Map<String, Object> unitList() {
        List<Unit> unitList = goodsDao.selectUnitList();
        HashMap<String, Object> map = new HashMap<>();
        map.put("rows", unitList);
        return map;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceVO goodsTypeSave(String goodsTypeName, Integer pId) {
        // 默认添加的是三级分类
        Integer goodsTypeState = 0;
        if (pId == 1) {
            //添加的是二级分类
            goodsTypeState = 1;
        }
        goodsDao.insertGoodsType(new GoodsType(goodsTypeName, goodsTypeState, pId));

        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceVO goodsTypeDelete(Integer goodsTypeId) {
        goodsDao.deleteGoodsType(goodsTypeId);
        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceVO saveGoods(Integer goodsId, Goods goods) {
        if (goods == null) {
            return new ServiceVO(ErrorCode.PARA_TYPE_ERROR_CODE, ErrorCode.PARA_TYPE_ERROR_MESS, null);
        }
        // 状态，初始值0
        goods.setState(0);
        // 库存数量
        goods.setInventoryQuantity(0);


        if (goodsId == null) { // 修改商品
            goodsDao.insertGoods(goods);
        } else { // 新增商品
            goodsDao.updateGoods(goods);
        }
        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }

    @Override
    public String getCode() {
        // 获取最大的商品编码
        Integer goodsCode = goodsDao.selectGoodsCode();
        String goodsCodeStr = String.format("%04d", goodsCode + 1);
        return goodsCodeStr;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ServiceVO deleteGoods(Integer goodsId) {
        Goods goods = goodsDao.selectGoods(goodsId);

        if (goods.getState() == 1) {
            return new ServiceVO(ErrorCode.STORED_ERROR_CODE, ErrorCode.STORED_ERROR_MESS, null);
        }
        if (goods.getState() == 2) {
            return new ServiceVO(ErrorCode.HAS_FORM_ERROR_CODE, ErrorCode.HAS_FORM_ERROR_MESS, null);

        }

        // 初始化状态0可以删除
        goodsDao.deleteGoods(goodsId);

        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }


    @Override
    public Map<String, Object> getNoOrHasInventoryQuantity(Integer page, Integer rows, String nameOrCode, Boolean flag) {
        Integer index = (page - 1) * rows;
        // 条件分页查询
        List<Goods> goodsList = goodsDao.selectPageNoOrHasInventoryQuantity(index, rows, nameOrCode, flag);

        // 根据nameOrCode查询数量
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        // 有库存
        if (flag) {
            queryWrapper.gt("inventory_quantity", 0);
        } else { // 无库存
            queryWrapper.le("inventory_quantity", 0);

        }
        if (nameOrCode!= null) {
            queryWrapper
                    .like("goods_name", nameOrCode)
                    .or()
                    .like("goods_code", nameOrCode);
        }

        Integer count = goodsDao.selectCount(queryWrapper);
        // 组装map
        Map<String, Object> map = new HashMap<>();
        map.put("total", count);
        map.put("rows", goodsList);
        return map;
    }


    @Override
    public Map<String, Object> listAlarm() {
        List<Goods> goodsList = goodsDao.selectGoodsList();
        // 组装map
        Map<String, Object> map = new HashMap<>();
        map.put("rows", goodsList);
        return map;
    }

    /**
     * 进货单保存
     *
     * @param purchaseNumber
     * @param purchaseList
     * @param purchaseListGoodsStr
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceVO savePurchaseList(String purchaseNumber, PurchaseList purchaseList, String purchaseListGoodsStr) {
        // 获取当前登录的用户id
        String userName = (String) SecurityUtils.getSubject().getPrincipal();
        //根据用户名查询用户信息
        User user = userDao.findUserByName(userName);
        Integer userId = user.getUserId();

        // 保存进货单
        purchaseList.setPurchaseNumber(purchaseNumber);
        purchaseList.setUserId(userId);

        purchaseListService.save(purchaseList);
        // 保存进货单对应的商品
        Gson gson = new Gson();
        List<PurchaseListGoods> purchaseListGoodsList = gson.fromJson(purchaseListGoodsStr, new TypeToken<List<PurchaseListGoods>>(){}.getType());

        for (PurchaseListGoods purchaseListGoods : purchaseListGoodsList) {
            purchaseListGoods.setPurchaseListId(purchaseList.getPurchaseListId());

            // 得到原来的库存
            Integer goodsId = purchaseListGoods.getGoodsId();
            Goods goods = goodsDao.selectGoods(goodsId);
            // 对应商品的库存增加
            Integer goodsNum = purchaseListGoods.getGoodsNum();
            goods.setInventoryQuantity(goods.getInventoryQuantity()+goodsNum);
            // 更新采购价格
            goods.setPurchasingPrice(purchaseListGoods.getPrice());
            // 商品状态
            goods.setState(2);

            goodsDao.updateById(goods);

        }

        purchaseListGoodsService.saveBatch(purchaseListGoodsList);

        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }


    /**
     * 退货单保存
     *
     * @param returnNumber
     * @param returnList
     * @param returnListGoodsStr
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ServiceVO saveReturnListGoods(String returnNumber, ReturnList returnList, String returnListGoodsStr) {
        // 获取当前登录的用户id
        String userName = (String) SecurityUtils.getSubject().getPrincipal();
        //根据用户名查询用户信息
        User user = userDao.findUserByName(userName);
        Integer userId = user.getUserId();

        // 保存进货单
       returnList.setUserId(userId);
       returnList.setReturnNumber(returnNumber);

        returnListService.save(returnList);
        // 保存进货单对应的商品
        Gson gson = new Gson();
        List<ReturnListGoods> returnListGoodsList = gson.fromJson(returnListGoodsStr, new TypeToken<List<ReturnListGoods>>(){}.getType());

        for (ReturnListGoods returnListGoods : returnListGoodsList) {
            // 设置退货单的id
            returnListGoods.setReturnListId(returnList.getReturnListId());

            // 得到原来的库存
            Integer goodsId = returnListGoods.getGoodsId();
            Goods goods = goodsDao.selectGoods(goodsId);
            // 对应商品的库存减少
            Integer goodsNum = returnListGoods.getGoodsNum();
            goods.setInventoryQuantity(goods.getInventoryQuantity()-goodsNum);
            // 更新对应的商品的库存
            goodsDao.updateById(goods);

        }

        returnListGoodsService.saveBatch(returnListGoodsList);

        return new ServiceVO(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, null);
    }

    /**
     * 退货单列表展示（可条件查询：单据号模糊、供应商、是否付款和日期区间）
     *
     * @param returnNumber
     * @param supplierId
     * @param state
     * @param sTime
     * @param eTime
     * @return
     */
    @Override
    public Map<String, Object> getReturnListList(String returnNumber, Integer supplierId, Integer state, String sTime, String eTime) {
        List<ReturnList> returnListList = returnListDao.selectListOfReturnList(returnNumber, supplierId, state, sTime, eTime);

        Map<String, Object> map = ResultUtil.toRowsMap(returnListList);
        return map;
    }
}
